/**
 * @file  MiraVector3D.h
 * @author Josep Sabater (jsabaterm@el.ub.edu)
 * @date   October, 2015
 * @version 1.0.0
 * @ingroup MiraGeometryLib
 * @brief  Interface of a vector of 3 dimensions.
 *
 *
 */
#ifndef MIRA_VECTOR_3D_H
#define MIRA_VECTOR_3D_H

#include <ostream>

#include "MiraVector2D.h"

namespace MiraGeometryLib{

   /**
    * @class Vector3D
    * @brief Implementation of the Vector 3D IFace
    */
    class Vector3D {

    public:
       /**
        * @brief Constructor for Vector3D.
        * @details This is the default constructor.
        * @return A vector3D object where its components (x, y, z) are both 0.
        */
        Vector3D(): x_(0), y_(0), z_(0){};
       /**
        * @brief Constructor for Vector3D.
        * @details Constructor that specifies the values of the vector.
        * @param x Component X.
        * @param y Component Y.
        * @param z Component Z.
        * @return A vector3D object where its components (x, y, z) are the ones
        * given by the caller.
        */
       Vector3D(const double& x, const double& y, const double& z) : x_(x), y_(y), z_(z){};
       Vector3D(const Vector2D& v) : x_(v.x()), y_(v.y()), z_(0){};

       double x() const { return x_; }
       void x(const double& x) { x_ = x; }
       double y() const { return y_; }
       void y(const double& y) { y_ = y;}
       double z() const { return z_; }
       void z(const double& z) { z_ = z; }

       Vector3D& operator = (Vector3D vect);
       Vector3D operator + (const Vector3D& vect) const;
       Vector3D operator - (const Vector3D& vect) const;
       friend std::ostream& operator << (std::ostream& os, const Vector3D& vect);
       Vector3D cross (const Vector3D& vect) const;
       double squaredNorm () const;
       double norm() const;
        bool isZero() const;

   private:
        double x_; //! < Component X of the 3D vector.
        double y_; //! < Component Y of the 3D vector.
        double z_; //! < Component Z of the 3D vector.

        static const int zeroRoundDigits_;
        /**
         * @brief Swaps of the date of given 3D vector with the data of this Vector2D.
         * @details This member function should never fail.
         * @param vect Vector3D to copy data from.
         * @return Nothing
         * @see        Assignemt Operator in C++
         * @see        https://en.wikipedia.org/wiki/Assignment_operator_(C%2B%2B)
         */
        void swap_(Vector3D& vect);
    };
}

#endif
